<script lang="ts" setup>
import { TableInstance } from 'element-plus';
import { deletePermission, listChildPermission, pagePermission } from '@/api';
import { useHeaderStore } from '@/stores/header';
import { Dept, MatchItem, Menu, OrderItem, Page } from '@/model';
import Creation from '@/views/setting/permission/creation.vue';

const headerStore = useHeaderStore();
// 检索条件的表单
const schForm = ref<Menu>({});
// 表格分页数据
const tableData = ref<Page<Menu>>({
  records: [] as Menu[],
  current: 0,
  pages: 0,
  size: 0,
  total: 0,
});
const expandRows = ref<Array<string>>([]);
const visible = ref<boolean>(false);
const openType = ref<string>('');
const currentNode = ref<Menu>();
const treeRef = ref<TableInstance>();

// 分页请求参数
const pageParam = ref<Page<Menu>>({});

/**
 * 分页请求
 * @param pageObj 分页请求信息
 */
const pageReq = (pageObj: Page<Menu>) => {
  pagePermission(pageObj).then((res) => {
    if (res.records && res.records.length) {
      tableData.value.records = res.records;
      tableData.value.current = Number(res.current);
      tableData.value.pages = Number(res.pages);
      tableData.value.size = Number(res.size);
      tableData.value.total = Number(res.total);
    } else {
      tableData.value.records = [];
    }
  });
};

/**
 * 懒加载执行函数
 * @param row 展开的行
 * @param treeNode 树节点
 * @param resolve
 */
const loadChildPermission = (
  row: Menu,
  treeNode: unknown,
  resolve: (date: Menu[]) => void,
) => {
  listChildPermission(row.id).then((res: Menu[]) => {
    resolve(res);
  });
};

/**
 * 刷新子节点数据
 * @param id 需要刷新子节点数据的节点id
 */
const refreshChildren = (id: string) => {
  if (!treeRef.value) return;
  const { lazyTreeNodeMap, treeData } = treeRef.value.store.states;
  if (!treeData.value[id]) {
    treeData.value[id] = {
      loading: false,
      loaded: true,
      level: '',
      lazy: true,
      expanded: true,
      children: [],
    };
  }
  treeData.value[id].loading = true;
  listChildPermission(id)
    .then((res: Menu[]) => {
      treeData.value[id].loading = false;
      treeData.value[id].loaded = true;
      treeData.value[id].exported = true;
      lazyTreeNodeMap.value[id] = res;
    })
    .catch(() => {
      treeData.value[id].loading = false;
      treeData.value[id].loaded = true;
    });
};

/**
 * 关闭弹窗时调用
 * @param open
 * @param type 单开弹窗的类型
 * @param currMenu 当前被选中的权限行
 */
const onCloseDialog = (open: boolean, type: string, currMenu: Menu | undefined) => {
  visible.value = open;
  openType.value = type;
  currentNode.value = currMenu;
};

/**
 * 初始化分页请求参数
 */
const initPageParam = () => {
  pageParam.value = {
    current: 1,
    size: 10,
    orderItems: new Array<OrderItem>({
      column: 'createAt',
      asc: false,
    }),
    matchItems: new Array<MatchItem>(<MatchItem>{
      column: 'parentId',
      value: '0',
      and: true,
    }),
  };
};

/**
 * 检索
 */
const onSearch = () => {
  if (!schForm.value) {
    return;
  }
  const matchItems = [];
  if (schForm.value.name) {
    matchItems.push(<MatchItem>{
      // 查询的时候字段名称为permissionName，正常显示的字段名叫name
      column: 'permissionName',
      value: schForm.value.name,
      and: true,
      operator: 'LIKE',
    });
  }
  if (schForm.value.type) {
    matchItems.push(<MatchItem>{
      column: 'type',
      value: schForm.value.type,
      and: true,
      operator: 'EQ',
    });
  }
  pageParam.value = {
    current: 1,
    size: 10,
    orderItems: new Array<OrderItem>({
      column: 'createAt',
      asc: false,
    }),
    matchItems,
  };
  pageReq(pageParam.value);
};

/**
 * 重置检索条件
 */
const onResetSchFrom = () => {
  schForm.value = {};
  initPageParam();
  pageReq(pageParam.value);
};

/**
 * 删除权限
 * @param row
 */
const onDelete = (row: Menu) => {
  deletePermission(row.id).then(() => refreshChildren(row.parentId));
};

/**
 * 点击编辑权限
 * @param row
 */
const onEdit = (row: Menu) => {
  onCloseDialog(true, 'update', row);
};

/**
 * 点击新增权限
 * @param row
 */
const onCreate = (row: Menu | undefined) => {
  onCloseDialog(true, 'create', row);
};

/**
 * 新增或编辑提交后调用
 */
const onSubmitted = (permission: Menu) => {
  if (permission.parentId === '0') {
    initPageParam();
    pageReq(pageParam.value);
  } else {
    refreshChildren(permission.parentId);
  }
  onCloseDialog(false, '', undefined);
};

/**
 * 当一行数据被点击时调用（懒加载）
 * 单击数据行展开或收起
 * @param row 数据行
 * @param col 列
 * @param e 绑定的点击事件
 */
const onRowClick = (row: Dept, col: any, e: any) => {
  if (
    e.currentTarget.firstElementChild.firstElementChild.firstElementChild.tagName ===
    'DIV'
  ) {
    e.currentTarget.firstElementChild.firstElementChild.firstElementChild.click();
  } else {
    e.currentTarget.firstElementChild.firstElementChild.firstElementChild.nextElementSibling.click();
  }
};

/**
 * 动态计算表格高度
 */
const tableHeight = computed(() => {
  return window.innerHeight - 360;
});

// 监听当前页变化，请求数据
watch(
  () => tableData.value.current,
  () => {
    pageParam.value.current = tableData.value.current;
    pageReq(pageParam.value);
  },
  { deep: true },
);

onMounted(() => {
  headerStore.$patch({
    title: '权限管理',
  });
  initPageParam();
  pageReq(pageParam.value);
  onCloseDialog(false, '', undefined);
});
</script>

<template>
  <div class="content-container">
    <!--搜索栏-->
    <div class="search-container">
      <el-scrollbar height="100px">
        <el-form :inline="true" :model="schForm" class="form-search" size="large">
          <el-form-item>
            <el-input
              class="input-search"
              v-model="schForm.name"
              placeholder="按权限名称搜索"
              clearable
            />
          </el-form-item>
          <el-form-item>
            <el-select
              class="input-search"
              v-model="schForm.type"
              placeholder="按权限类型搜索"
              clearable
            >
              <el-option label="菜单" value="1" />
              <el-option label="按钮" value="2" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-tooltip content="搜索" placement="top" effect="light" :show-after="500">
              <el-button @click="onSearch" class="btn-search">
                <el-icon size="18px">
                  <i-ep-search />
                </el-icon>
              </el-button>
            </el-tooltip>
          </el-form-item>
          <el-form-item>
            <el-tooltip content="重置" placement="top" effect="light" :show-after="500">
              <el-button @click="onResetSchFrom" class="btn-reset">
                <el-icon size="18px">
                  <i-ep-refresh-left />
                </el-icon>
              </el-button>
            </el-tooltip>
          </el-form-item>
        </el-form>
      </el-scrollbar>
    </div>
    <!--功能栏-->
    <div class="function-container">
      <span class="title">权限列表</span>
      <el-tooltip
        content="新增根节点菜单"
        placement="top"
        effect="light"
        :show-after="500"
      >
        <el-button class="btn-create" circle @click.stop="onCreate(undefined)">
          <el-icon>
            <i-ep-plus />
          </el-icon>
        </el-button>
      </el-tooltip>
    </div>
    <!--数据栏-->
    <div class="data-container">
      <el-table
        :height="tableHeight"
        :data="tableData.records"
        ref="treeRef"
        row-key="id"
        lazy
        :load="loadChildPermission"
        @row-click="onRowClick"
        :expand-row-keys="expandRows"
      >
        <el-table-column prop="name" label="菜单/权限名称" min-width="200" />
        <el-table-column prop="type" label="类型">
          <template #default="scope">
            {{ scope.row.type === 1 ? '菜单' : '按钮' }}
          </template>
        </el-table-column>
        <el-table-column prop="iconName" label="图标">
          <template #default="scope">
            <el-icon size="20px">
              <component :is="scope.row.iconName" />
            </el-icon>
          </template>
        </el-table-column>
        <el-table-column prop="iconColor" label="图标颜色">
          <template #default="scope">
            <div
              :style="
                'width: 20px; height: 20px; background-color: ' + scope.row.iconColor
              "
            ></div>
          </template>
        </el-table-column>
        <el-table-column
          prop="url"
          label="权限路径"
          min-width="120"
          :show-overflow-tooltip="true"
        />
        <el-table-column prop="weight" label="权重/排序" min-width="100" />
        <el-table-column prop="enabled" label="启用" min-width="120">
          <template #default="scope">
            <el-tag
              effect="dark"
              :type="scope.row.enabled ? 'success' : 'info'"
              disable-transitions
            >{{ scope.row.enabled ? '启用' : '停用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          prop="description"
          label="备注"
          min-width="200"
          :show-overflow-tooltip="true"
        />
        <el-table-column prop="operate" label="操作" width="160" :fixed="'right'">
          <template #default="scope">
            <el-tooltip content="编辑" placement="top" effect="light" :show-after="500">
              <el-button class="btn-edit" circle @click.stop="onEdit(scope.row)">
                <i-ep-edit />
              </el-button>
            </el-tooltip>
            <el-tooltip content="新增" placement="top" effect="light" :show-after="500">
              <el-button
                class="btn-create"
                circle
                @click.stop="onCreate(scope.row)"
                :disabled="scope.row.type === 2"
              >
                <i-ep-plus />
              </el-button>
            </el-tooltip>
            <el-popconfirm
              title="删除会删除当前节点以及其子节点所有数据，确定删除？"
              confirm-button-text="确定"
              cancel-button-text="取消"
              cancel-button-type="success"
              confirm-button-type="danger"
              @confirm="onDelete(scope.row)"
            >
              <template #reference>
                <el-button class="btn-delete" circle>
                  <i-ep-delete />
                </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        :background="true"
        v-model:current-page="tableData.current"
        v-model:page-size="tableData.size"
        :total="tableData.total"
        :page-count="tableData.pages"
        :pager-count="5"
        layout="prev, pager, next"
        class="table-pagination"
      >
      </el-pagination>
    </div>
    <!--弹窗-新增-->
    <creation
      :visible="visible"
      :current-row="currentNode"
      :type="openType"
      @close-dialog="onCloseDialog"
      @submitted="onSubmitted"
    />
  </div>
</template>

<style lang="scss" scoped></style>
